﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameDataLibrary;

namespace UtopianGame
{
    public static class Nation
    {
        const int POLICY_LIST_SIZE = 5;
        const int REGION_COUNT = 7;

        //Integer values which represent resources
        //the player has access to
        public static int moneyInTreasury;
        public static int goodwillAmount;

        //Initial poverty count. Used at the end for scoring.
        public static int initialPovertyCount;

        //Integer values which represent data about
        //the player's Nation.
        
        public static int educationIndex;
        public static int crimeIndex;
        public static int healthIndex;

        //Lists of objects that can be referenced by
        //the Nation class.
        public static List<Region> regionList;
        public static List<Policy> policyList;
        public static List<Policy> currentlySuggestedPolicies;
        public static List<StatusEffect> statusEffectList;
        public static List<Infrastructure> infrastructureList;

        public static void Init()
        {
            moneyInTreasury = 10000;
            goodwillAmount = 0;

            regionList = new List<Region>();
            Random regionRNG = new Random();
            for (int i = 0; i < REGION_COUNT; i++)
            {
                regionList.Add(new Region());
                //Initialize regions
                regionList[i].populationCount = regionRNG.Next(90,150);
                regionList[i].costOfLiving = regionRNG.Next(1500,2000);
                regionList[i].educationIndex = regionRNG.Next(30,50);
                regionList[i].crimeIndex = regionRNG.Next(50,75);
                regionList[i].healthIndex = regionRNG.Next(30, 50);
                regionList[i].povertyIndex = getPovertyCount();
                regionList[i].industrialIndex = 0;
                regionList[i].researchIndex = 0;
                regionList[i].averageIncome = regionRNG.Next(800,1700);
                regionList[i].infrastructureList = new List<String>();
            }
            policyList = new List<Policy>();
            statusEffectList = new List<StatusEffect>();
            infrastructureList = new List<Infrastructure>();

            initialPovertyCount = getPovertyCount();
        }

        public static int getPovertyCount(int regionNumber)
        {
            int povertyCount = 0;
            int populationCount = regionList[regionNumber].populationCount;
            int averageIncome = regionList[regionNumber].averageIncome;
            int costOfLiving = regionList[regionNumber].costOfLiving;
            double povertyCountMultiplier = (.5 + (((double)costOfLiving - (double)averageIncome) / (double)costOfLiving));
            povertyCount = populationCount;
            povertyCount = Math.Min(populationCount, (int)(Math.Round(povertyCount * povertyCountMultiplier)));

            return povertyCount;
        }

        public static int getPopulationCount()
        {
            int totalCount = 0;
            for (int i = 0; i < regionList.Count; i++)
            {
                totalCount += regionList[i].populationCount;
            }
            return totalCount;
        }

        public static int getAverageCrimeIndex()
        {
            int averageCrime = 0;
            for (int i = 0; i < regionList.Count; i++)
            {
                averageCrime += regionList[i].crimeIndex;
            }
            averageCrime /= regionList.Count;
            return averageCrime;
        }

        public static int getAverageHealthIndex()
        {
            int averageHealth = 0;
            for (int i = 0; i < regionList.Count; i++)
            {
                averageHealth += regionList[i].healthIndex;
            }
            averageHealth /= regionList.Count;
            return averageHealth;
        }

        public static int getAverageEducationIndex()
        {
            int averageEducation = 0;
            for (int i = 0; i < regionList.Count; i++)
            {
                averageEducation += regionList[i].educationIndex;
            }
            averageEducation /= regionList.Count;
            return averageEducation;
        }

        public static int getAverageCostOfLiving()
        {
            int averageCostOfLiving = 0;
            for (int i = 0; i < regionList.Count; i++)
            {
                averageCostOfLiving += regionList[i].costOfLiving;
            }
            averageCostOfLiving /= regionList.Count;
            return averageCostOfLiving;
        }

        public static int getAverageIncome()
        {
            int averageIncome = 0;
            for (int i = 0; i < regionList.Count; i++)
            {
                averageIncome += regionList[i].averageIncome;
            }
            averageIncome /= regionList.Count;
            return averageIncome;
        }

        public static int getPovertyCount()
        {
            int povertyCount = 0;
            for (int i = 0; i < regionList.Count; i++)
            {
                povertyCount += getPovertyCount(i);
            }
            return povertyCount;
        }

        public static void GetNewRandomPolicies(Random rGenerator)
        {
            //Clear the PolicyList
            policyList = new List<Policy>();
            for (int i = 0; i < POLICY_LIST_SIZE; i++)
            {
                int policyNumber = rGenerator.Next(GlobalDataHolder.policyArray.Length);    //generates a random number from 0 to policyArray.Length
                while (!PolicyIsValid(policyNumber, i))
                {
                    policyNumber = rGenerator.Next(GlobalDataHolder.policyArray.Length);    //generates a random number from 0 to policyArray.Length
                }

                policyList.Add(new Policy(GlobalDataHolder.policyArray[policyNumber].xmlData));
            }
        }

        public static void GetRandomEvents(int randomEventCount, Random rGenerator)
        {
            
            for (int i = 0; i < randomEventCount; i++)
            {
                int randomEventNumber = rGenerator.Next(GlobalDataHolder.randomEventArray.Length);  //generates a random number from 0 to randomEventArray.Length
                while (GlobalDataHolder.randomEventArray[randomEventNumber].runEvent() == false)    //If false is returned, the event didn't meet its prerequisites.
                {
                    randomEventNumber = rGenerator.Next(GlobalDataHolder.randomEventArray.Length);  //generates a random number from 0 to randomEventArray.Length
                }
            }
        }

        public static bool PolicyIsValid(int policyNumber, int policyArrayIndex)
        {
            Policy currentPolicy = GlobalDataHolder.policyArray[policyNumber];
            //Check to ensure that the current policy has not already been added to policyArray (to prevent redundancy)
            for (int i = 0; i < policyArrayIndex; i++)
            {
                if (currentPolicy.xmlData == GlobalDataHolder.policyArray[i].xmlData)
                {
                    return false;
                }
            }
            return true;
        }
    }
}
